package excel

import (
	"errors"
	"github.com/360EntSecGroup-Skylar/excelize/v2"
	"github.com/gin-gonic/gin"
	"strconv"
)

func CheckExcel(c *gin.Context, success_titles []string) (r [][]string, err error) {
	header, err := c.FormFile("excel")
	if err != nil {
		err = errors.New("excel error")
		return
	}
	multipart_file, err := header.Open()
	if err != nil {
		err = errors.New("excel error")
		return
	}
	defer multipart_file.Close()

	f, err := excelize.OpenReader(multipart_file)
	if err != nil {
		err = errors.New("excel error")
		return
	}

	sheet_name := f.GetSheetName(0)
	rows, err := f.GetRows(sheet_name)
	if len(rows) < 2 {
		err = errors.New("excel error")
		return
	}

	// 第二行是标题行
	titles := rows[1]
	// 校验长度
	if len(titles) < len(success_titles) {
		for i := len(titles); i < len(success_titles); i++ {
			titles = append(titles, "")
		}
	}
	for i, v := range success_titles {
		if v != titles[i] {
			err = errors.New("excel表格式不正确,第" + strconv.Itoa(i+1) + "列应是" + success_titles[i])
			return
		}
	}
	return rows, nil
}

type Excel_CB func(row []string) (err error)

func Execute(c *gin.Context, cb Excel_CB, headerStr []string) (err error) {
	//在外面开事务
	rows, err := CheckExcel(c, headerStr)
	if err != nil {
		return
	}

	error_units := ""
	// byte A
	var A = []byte("A")
	var Clo = make([]byte, 1)

	//列数
	clomunNumber := len(headerStr)

	for i, row := range rows {
		if i < 2 {
			//忽略第一行：描述行
			//忽略第二行：标题行
			continue
		}

		length := len(row)
		if length < clomunNumber {
			for i := length; i < clomunNumber; i++ {
				row = append(row, "")
			}
		}

		// check excel 数据正确
		var is_emptystr string
		for j, _ := range headerStr {
			is_emptystr += row[j]
		}
		if is_emptystr == "" {
			continue
		}

		for j, clomun := range headerStr {
			// 开头带 * 为必填项
			if row[j] == "" && string(clomun[0]) == "*" {
				Clo[0] = A[0] + byte(j)
				// 获取该错误单元格
				error_units += string(Clo) + strconv.Itoa(i+1) + "，"
				continue
			}
		}

		if len(error_units) > 0 {
			// 只要excel中存在错误，本次导入就只查询错误信息，不进行导入
			continue
		}

		//开始导入
		//execute 行操作
		err = cb(row)

		if err != nil {
			return
		}
	}
	if len(error_units) > 0 {
		// 数据错误，反馈错误单元
		return errors.New("文件中：" + error_units + "单元格不符合输入规范，请修复后重新上传")
	}
	return nil
}
